# from exts import db
# from common import constant
# from app.order.model import Order, OrderSku
# 
# 
# class CheckOrder(Order):
#     __tablename__ = 'check_order'
#     warehouse_id = db.Column(db.Integer, db.ForeignKey('warehouse.id'))
# 
#     order_skus = db.relationship("CheckOrderSku", back_populates='order', cascade="all, delete, delete-orphan")
# 
# 
# class CheckOrderSku(OrderSku):
#     __tablename__ = 'check_order_sku'
# 
#     before_num = db.Column(db.DECIMAL(20, constant.COMMON_DECIMAL), default=0)  # 盘点前数量，在盘点生效后保存，用于撤销


from exts import db
from common import constant
from app.order.model_mixin import OrderModelMixin
from common.base_model import BasicModelMixin, CompanyMixin, CreateMixin, UpdateMixin, DeleteMixin
from common import errors
from app.storage.storage_record.model import StorageRecord
from app.storage.storage_flow.model import StorageFlow
from common.constant import OrderStatus, OrderType
from datetime import datetime
from common.utils import get_default_date


class CheckOrder(BasicModelMixin, db.Model, OrderModelMixin, CompanyMixin, CreateMixin, UpdateMixin, DeleteMixin):
    __tablename__ = 'check_order'

    warehouse_id = db.Column(db.Integer, db.ForeignKey('warehouse.id'))
    warehouse = db.relationship("Warehouse")

    order_skus = db.relationship("CheckOrderSku", back_populates='check_order',
                                 cascade="all, delete, delete-orphan")

    def save_draft(self, order_skus_json, image_ids, **kwargs):
        self.check_draft_status()
        # 更新order
        self.update(**kwargs)
        # 更新 order_sku
        for order_sku in self.order_skus:
            order_sku.hard_delete()  # 先删
        for order_sku_json in order_skus_json:
            # 获取当前库存，填入before_num
            storage_record = StorageRecord.query.filter_by(
                warehouse_id=self.warehouse_id, sku_id=order_sku_json["sku_id"], unit_id=order_sku_json['unit_id']
            ).first()
            if storage_record:
                order_sku_json["before_num"] = storage_record.num
            else:
                order_sku_json["before_num"] = 0
            CheckOrderSku.create(order_id=self.id, **order_sku_json)  # 后增

        # 更新images
        self.update_images(image_ids)
        db.session.commit()

    def update_images(self, image_ids):
        self.update_images_by_belong_type(image_ids, constant.FileBelongType.CHECK_ORDER)

    def submit(self):
        """入库"""
        self.status = OrderStatus.SUCCESS  # 修改order状态
        self.date = get_default_date(None)
        self.update_warehouse_record()  # 更新库存
        self.create_warehouse_flow()  # 创建库存流水
        db.session.commit()

    def revoke(self):
        """回退入库，回退财务"""
        if self.status != OrderStatus.SUCCESS:
            raise errors.BadRequestError('无法撤销，只有已完成单据可撤销！')
        # 只可撤销最近的一笔盘点单
        last_check_order = CheckOrder.query. \
            filter_by_company_id(status=OrderStatus.SUCCESS).order_by(CheckOrder.date.desc()).first()
        if last_check_order.id != self.id:
            raise errors.BadRequestError('无法撤销，只可撤销最近的一笔盘点单！')

        self.status = OrderStatus.REVOKE  # 修改order状态
        self.revoke_warehouse_record()  # 回退库存
        self.delete_warehouse_flow()  # 删除库存流水
        db.session.commit()

    def update_warehouse_record(self):
        """盘点， 直接修改数量, 不修改成本单价"""
        for order_sku in self.order_skus:
            """"""
            # get or create
            storage_record = StorageRecord.query.filter_by(
                warehouse_id=self.warehouse_id, sku_id=order_sku.sku_id, unit_id=order_sku.unit_id
            ).first()
            if storage_record is None:
                storage_record = StorageRecord.create(
                    warehouse_id=self.warehouse_id, sku_id=order_sku.sku_id, unit_id=order_sku.unit_id,
                    commit=True
                )
            # 减少库存数量
            storage_record.num = order_sku.num

    def revoke_warehouse_record(self):
        """盘点撤销 修改为上次"""
        for order_sku in self.order_skus:
            storage_record = StorageRecord.query.filter_by(
                warehouse_id=self.warehouse_id, sku_id=order_sku.sku_id, unit_id=order_sku.unit_id
            ).first()
            storage_record.num = order_sku.before_num

    def create_warehouse_flow(self):
        for order_sku in self.order_skus:
            # 盘点前数量 在 save_draft 时会从数据库中取出
            StorageFlow.create(
                warehouse_id=self.warehouse_id, sku_id=order_sku.sku_id, unit_id=order_sku.unit_id,
                order_type=OrderType.CHECK, order_id=self.id, num=order_sku.num-order_sku.before_num,
            )

    def delete_warehouse_flow(self):
        for order_sku in self.order_skus:
            StorageFlow.query.filter_by(
                warehouse_id=self.warehouse_id, sku_id=order_sku.sku_id, unit_id=order_sku.unit_id,
                order_type=OrderType.CHECK, order_id=self.id,
            ).first().hard_delete()

    @classmethod
    def generate_order_sn_check(cls, prefix='PD'):
        return cls.generate_order_sn(prefix)


class CheckOrderSku(BasicModelMixin, db.Model, CompanyMixin, CreateMixin, DeleteMixin):
    __tablename__ = 'check_order_sku'

    id = db.Column(db.Integer, primary_key=True)
    order_id = db.Column(db.Integer, db.ForeignKey('check_order.id'))
    check_order = db.relationship("CheckOrder", foreign_keys="CheckOrderSku.order_id")

    sku_id = db.Column(db.Integer, db.ForeignKey('sku.id'))
    unit_id = db.Column(db.Integer, db.ForeignKey('unit.id'))

    num = db.Column(db.DECIMAL(20, constant.COMMON_DECIMAL), default=0)  # 数量
    before_num = db.Column(db.DECIMAL(20, constant.COMMON_DECIMAL), default=0)  # 盘点前数量，在盘点生效后保存，用于撤销

    sku = db.relationship("Sku")
    unit = db.relationship("Unit")
